import React, {Component} from 'react'
import {connect} from 'react-redux'
import {keywordChange, searched, loadedMusicSrc, switchSearchPage, selectMusic, searching} from '../../actions/content-change'
import F from 'lodash/fp'
import MusicItem from './music-item.jsx'
import Pagination from '../Pagination.jsx'


const SearchInput = ({keyword, onChange, search, isSearching}) => {
    return (<div className="am-input-group">
        <input
            value={keyword}
            onChange={({target}) => onChange(target.value)}
            onKeyPress={ev => {
                if (ev.key === 'Enter') {
                    keyword && search(keyword)
                    ev.preventDefault()
                }
            }}
            type="text"
            className="am-form-field"
            placeholder="搜索音乐"
        />
        {
            isSearching
            ? <span className="am-input-group-label"><i className="am-icon-spinner am-icon-spin"></i></span>
            : <span className="am-input-group-label" onClick={() => keyword && search(keyword)}>搜索</span>
        }
    </div>)
}

// Promise a => a->a
const then = fn => promise => promise.then(fn)

class MusicSearch extends Component {
    search(keyword) {
        this.props.searching()
        keyword && fetch(`/music/search/${keyword}`)
            .then(_ => _.json())
            .then(F.take(25))
            .then(F.reduce((p, t) => F.set(t.hash, t, p), {}))
            .then(this.props.searched)
    }

    isLoaded(song) {
        return !!F.get('src', song)
    }

    loadMusicSrc(song) {
        return this.isLoaded(song) 
            ? Promise.resolve(song)
            : fetch(`/music/${song.hash}`)
                .then(_ => _.json())
                .then(this.props.loadedMusicSrc)
                .then(F.get('song'))
    }

    render () {
        let {list, curPage, keyword, curSrc, keywordChange, play, pause, selectMusic, selected, isSearching} = this.props

        let genMusicItem = t => <MusicItem {...t}
            curSrc={curSrc}
            key={t.hash}
            play={F.compose(then(play), then(F.get('src')), this.loadMusicSrc.bind(this, t))}
            pause={pause}
            select={F.compose(then(selectMusic), this.loadMusicSrc.bind(this, t))}
            selected={selected}
        />;
        
        let filterPage = F.compose(F.map(genMusicItem), F.slice(curPage * 5, (curPage + 1) * 5), F.values)
        
        return (
            <div>
                <div className="music-search">
                    <SearchInput keyword={keyword} onChange={keywordChange} search={this.search.bind(this)} isSearching={isSearching} />
                </div>
                <div className="vip-music-wp">
                    {list && F.size(list) > 0 ?
                        <ul>
                            {filterPage(list)}
                        </ul>
                    : null }
                    <Pagination limit={5} count={F.size(list)} onSwitch={this.props.switchPage} />
                </div>
            </div>
        )
    }
}

export default connect(
    ({music}) => ({
        keyword: music.search.keyword,
        list: music.search.list,
        curPage: music.search.curPage || 0,
        curSrc: music.curSrc,
        isSearching: music.search.isSearching
    })
    , (dispatch, props) => (
        { keywordChange:    F.compose(dispatch, keywordChange)
        , searching:         F.compose(dispatch, searching)
        , searched:         F.compose(dispatch, searched)
        , loadedMusicSrc:   F.compose(dispatch, loadedMusicSrc)
        , switchPage:       F.compose(dispatch, switchSearchPage)
        }
    )
)(MusicSearch)